package com.roin.tools.controller;

import com.roin.tools.App;
import com.roin.tools.service.DirCompareService;
import com.roin.tools.service.DuplicateFileService;
import com.roin.tools.utils.DialogUtil;
import com.roin.tools.utils.StringUtils;
import com.roin.tools.views.OrderNumberCell;
import com.roin.tools.vo.DirCompareFile;
import com.roin.tools.vo.DuplicateFile;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.util.Callback;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;


/**
 * 文件夹对比控制类
 * @author Roin
 */
public class DirCompareController extends AbstractController {

    private final static String DOT = ".";

    private boolean isMd5 = true;

    private DirCompareService dirCompareService;

    private List<String> audioTypeList = new ArrayList<String>(Arrays.asList(".mp3",".wav",".flac",".wma",".ogg",".aac",".ape"));
    private List<String> videoTypeList = new ArrayList<String>(Arrays.asList(".avi",".wmv",".mpg",".mpeg",".mov",".rm",".ram",".swf",".flv",".mp4",".3GP",".mkv",".rmvb",".m4v",".ogg"));
    private List<String> officeTypeList = new ArrayList<String>(Arrays.asList(".doc",".docx",".xls",".xlsx",".ppt",".pptx"));
    private List<String> compressedTypeList = new ArrayList<String>(Arrays.asList(".rar",".zip",".gz",".z",".7z"));;
    private List<String> imageTypeList = new ArrayList<String>(Arrays.asList("bmp",".dib",".emf",".gif",".icb",".ico",".jpg",".jpeg",".pbm",".pcd",".pcx",".pgm",".png",".ppm",".psd",".psp",".rle",".sgi",".tga",".tif"));;

    @FXML
    private TextField sourceDir;
    @FXML
    private TextField targetDir;
    @FXML
    private Button sourceBtn;
    @FXML
    private Button targetBtn;
    @FXML
    private TextField fileTypes;
    @FXML
    private CheckBox audioTypes;
    @FXML
    private CheckBox videoTypes;
    @FXML
    private CheckBox officeTypes;
    @FXML
    private CheckBox compressedTypes;
    @FXML
    private CheckBox imageTypes;
    @FXML
    private CheckBox isCopy;
    @FXML
    private CheckBox isKeepPath;
    @FXML
    private TextField copyDir;
    @FXML
    private Button copyDirBtn;
    @FXML
    private TableView<DirCompareFile> resultTableView;
    @FXML
    private TableColumn indexColumn;
    @FXML
    private TableColumn<DirCompareFile,File> fileColumn;
    @FXML
    private TableColumn handlerColumn;

    DirSelectButtonHandler dirSelectButtonHandler = new DirSelectButtonHandler();


    @FXML
    public void initialize() {
        super.init();
        dirCompareService = new DirCompareService();
        sourceBtn.setOnAction(dirSelectButtonHandler);
        targetBtn.setOnAction(dirSelectButtonHandler);
        copyDirBtn.setOnAction(dirSelectButtonHandler);

        //文件对比方式切换事件处理
        isCopy.selectedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldValue, Boolean newValue) {
                isKeepPath.setDisable(!newValue);
                copyDir.setDisable(!newValue);
                copyDirBtn.setDisable(!newValue);
            }
        });
    }

    @FXML
    public void exchangeDir(){
        String tempPath = sourceDir.getText();
        sourceDir.setText(targetDir.getText());
        targetDir.setText(tempPath);
    }

    private class DirSelectButtonHandler implements EventHandler<ActionEvent>{
        @Override
        public void handle(ActionEvent evt) {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setTitle("选择目录");
            TextField textField = null;
            if (evt.getSource().equals(sourceBtn)) {
                textField = sourceDir;
            } else if (evt.getSource().equals(targetBtn)) {
                textField = targetDir;
            }else if(evt.getSource().equals(copyDirBtn)) {
                textField = copyDir;
            }
            if (textField==null){
                return;
            }
            String preDir = textField.getText();
            if (preDir != null && preDir != "") {
                File perFile = new File(preDir);
                if(perFile.exists()){
                    directoryChooser.setInitialDirectory(perFile);
                }
            }
            File file = directoryChooser.showDialog(App.getStage());
            //选择的文件夹路径
            if (file != null) {
                String path = file.getPath();
                textField.setText(path);
            }
        }
    }


    /**
     * 开始比较
     */
    @FXML
    private void startCompare() {
        resultTableView.setItems(FXCollections.emptyObservableList());
        String sourceDirStr = sourceDir.getText();
        String targetDirStr = targetDir.getText();
        String fileTypesStr = fileTypes.getText();
        File sourceDir_ = new File(sourceDirStr);
        File targetDir_ = new File(targetDirStr);

        if (!sourceDir_.exists()) {
            DialogUtil.alert("请选择源目录");
            return;
        }
        if (!targetDir_.exists()) {
            DialogUtil.alert("请选择目标目录");
            return;
        }

        boolean isCopyVal = isCopy.isSelected();
        String copyPath = copyDir.getText();
        if (isCopyVal && StringUtils.isEmpty(copyPath)){
            DialogUtil.alert("请选择复制目录");
            return;
        }

        Set<String> fileTypeLimitList = new HashSet<>(2);
        if (StringUtils.isNotEmpty(fileTypesStr)) {
            String[] fileTypeLimitArray = fileTypesStr.split(",");
            for (String s : fileTypeLimitArray) {
                fileTypeLimitList.add(DOT + s);
            }
        }
        if(audioTypes.isSelected()){
            fileTypeLimitList.addAll(audioTypeList);
        }
        if(videoTypes.isSelected()){
            fileTypeLimitList.addAll(videoTypeList);
        }
        if(imageTypes.isSelected()){
            fileTypeLimitList.addAll(imageTypeList);
        }
        if(compressedTypes.isSelected()){
            fileTypeLimitList.addAll(compressedTypeList);
        }
        if(officeTypes.isSelected()){
            fileTypeLimitList.addAll(officeTypeList);
        }

        try {
            List<File> resultList = dirCompareService.compareDir(sourceDir_,targetDir_,fileTypeLimitList,isCopyVal,copyPath,isKeepPath.isSelected());

            System.out.println("共找到了"+resultList.size()+"个文件");
            if(resultList.isEmpty()){
                DialogUtil.alert("没有找到重复文件");
                return;
            }

            ObservableList<DirCompareFile> list =FXCollections.observableArrayList();
            for (File file : resultList) {
                list.add(new DirCompareFile(file,file.getAbsolutePath()));
            }
            rendererResultView(list);

        } catch (Exception e) {
            e.printStackTrace();
            DialogUtil.alertException(e);
        }
    }

    private void rendererResultView(ObservableList<DirCompareFile> data){
        //相当于java中的ArrayList
        resultTableView.setItems(data);
        indexColumn.setCellFactory(new OrderNumberCell<>());
        fileColumn.setCellValueFactory(new PropertyValueFactory<DirCompareFile,  File>("file"));
        fileColumn.setCellFactory(new Callback<>() {
            @Override
            public TableCell<DirCompareFile, File> call(TableColumn<DirCompareFile, File> duplicateFileListTableColumn) {
                return new TableCell<>() {
                    @Override
                    protected void updateItem(File file, boolean isEmpty) {
                        super.updateItem(file, isEmpty);
                        if (!isEmpty) {
                            Label label = new Label(file.getAbsolutePath());
                            label.setUserData(file);
                            this.setGraphic(label);
                        }
                    }
                };
            }
        });
        handlerColumn.setCellValueFactory(new PropertyValueFactory<DirCompareFile,  File>("file"));
        handlerColumn.setCellFactory(new Callback<TableColumn, TableCell>() {
            @Override
            public TableCell call(TableColumn tableColumn) {
                return new TableCell<ObservableList<File>,File>(){
                    @Override
                    protected void updateItem(File file, boolean isEmpty) {
                        super.updateItem(file, isEmpty);
                        if (!isEmpty){
                            HBox hBox = new HBox();
                            hBox.setSpacing(5);
                            hBox.setUserData(file);
                            hBox.setAlignment(Pos.CENTER);
                            Button delBtn = new Button("删除");
                            delBtn.setOnAction(delButtonHandler);
                            Button moveBtn = new Button("移动");
                            moveBtn.setOnAction(moveButtonHandler);
                            Button copyBtn = new Button("复制");
                            copyBtn.setOnAction(copyButtonHandler);
                            hBox.getChildren().addAll(delBtn,moveBtn,copyBtn);
                            this.setGraphic(hBox);
                        }
                    }
                };
            }
        });

    }

    /**
     * 删除文件操作处理器
     */
    private EventHandler delButtonHandler = event -> {
        Button button = (Button) event.getSource();
        Parent parent = button.getParent();
        File file = (File) parent.getUserData();
        System.gc();
        if(file.exists() && file.delete()){
            parent.setDisable(true);

        }
    };

    /**
     * 移动文件操作处理器
     */
    private EventHandler moveButtonHandler = event -> {
        Button button = (Button) event.getSource();
        Parent parent = button.getParent();
        File file = (File) parent.getUserData();
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle("选择目录");
        File dir = directoryChooser.showDialog(App.getStage());
        //选择的文件夹路径
        if (file != null && dir!=null && file.exists() && dir.exists()) {
            System.gc();
            boolean moveSuccess = file.renameTo(new File(dir.getPath()+File.separator+file.getName()));
            if (moveSuccess){
                parent.setDisable(true);
            }
        }
    };
    /**
     * 复制文件操作处理器
     */
    private EventHandler copyButtonHandler = event -> {
        Button button = (Button) event.getSource();
        Parent parent = button.getParent();
        File file = (File) parent.getUserData();
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle("选择目录");
        File dir = directoryChooser.showDialog(App.getStage());
        //选择的文件夹路径
        if (file != null && dir!=null && file.exists() && dir.exists()) {
            button.setDisable(true);
            try{
                FileInputStream fis = new FileInputStream(file);//创建输入流对象
                FileOutputStream fos = new FileOutputStream(dir.getPath()+File.separator+file.getName()); //创建输出流对象
                byte[] datas = new byte[1024*8];//创建搬运工具
                int len = 0;//创建长度
                while((len = fis.read(datas))!=-1)//循环读取数据
                {
                    fos.write(datas,0,len);
                }
                fis.close();//释放资源
                fos.close();//释放资源
            }catch (Exception e){
                e.printStackTrace();
            }
            button.setDisable(false);
        }
    };


}
